package net.wantongtech.xa.uploadbasicinfo.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.wtkj.vo.dzzf.base.xxjh.MessageSend;
import lombok.extern.slf4j.Slf4j;
import net.wantongtech.xa.uploadbasicinfo.dao.ExportPSBCBatchDeductionDao;
import net.wantongtech.xa.uploadbasicinfo.vo.ExportVo;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.FileOutputStream;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 导出邮储银行批量扣款数据服务实现
 *
 * @author MaShibo
 * 2020/12/10 0010
 */
@Slf4j
@Service
public class ExportPSBCBatchDeductionService {


    public static final int PER_NUM = 1000;

    private ObjectMapper objectMapper = new ObjectMapper();

    @Resource
    private ExportPSBCBatchDeductionDao exportPSBCBatchDeductionDao;

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;


    public void export() {
        Integer total = exportPSBCBatchDeductionDao.queryExportDataNum();
        log.info("共查询到{}条可导出数据", total);
        if (total == 0) {
            return;
        }
        int num = (int) Math.ceil((double) total / PER_NUM);
        log.info("每次查询{}条数据，共需要查询{}次", PER_NUM, num);
        List<Future<List<ExportVo>>> futureList = Lists.newArrayList();
        for (int i = 1; i <= num; i++) {
            int start = PER_NUM * (i - 1) + 1;
            int end = PER_NUM * i;
            if (end > total) {
                end = total;
            }
            Future<List<ExportVo>> future = taskExecutor.submit(new ExportDeductionThread(start, end));
            futureList.add(future);
        }

        List<ExportVo> allSendList = Lists.newArrayList();
        for (Future<List<ExportVo>> future : futureList) {
            try {
                List<ExportVo> sendList = future.get();
                allSendList.addAll(sendList);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error(e.getMessage(), e);
            } catch (ExecutionException e) {
                log.error(e.getMessage());
            }
        }

        allSendList.sort(Comparator.comparing(ExportVo::getMsgId));

        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("统计");
        sheet.setDefaultColumnWidth(15);
        XSSFRow titleRow = sheet.createRow(0);
        titleRow.createCell(0).setCellValue("批量扣款包号");
        titleRow.createCell(1).setCellValue("交易数量");
        titleRow.createCell(2).setCellValue("交易金额/分");
        for (int i = 0; i < allSendList.size(); i++) {
            ExportVo messageSend = allSendList.get(i);
            int rowNum = i + 1;
            XSSFRow row = sheet.createRow(rowNum);
            row.createCell(0).setCellValue(String.valueOf(messageSend.getMsgId()));
            row.createCell(1).setCellValue(messageSend.getCount().toString());
            row.createCell(2).setCellValue(String.valueOf(messageSend.getAmount()));
        }
        try (FileOutputStream fileOut = new FileOutputStream("psbc.xlsx")) {
            workbook.write(fileOut);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

    }

    class ExportDeductionThread implements Callable<List<ExportVo>> {

        private final int start;

        private final int end;

        public ExportDeductionThread(int start, int end) {
            this.start = start;
            this.end = end;
        }

        @Override
        public List<ExportVo> call() throws Exception {
            log.info("开始查询{}-{}的数据", start, end);
            List<ExportVo> sendList = Lists.newArrayList();
            try {
                List<MessageSend> messageSendList = exportPSBCBatchDeductionDao.queryExportMsgSendByRowNum(start, end);
                for (MessageSend messageSend : messageSendList) {
                    Integer count = messageSend.getCount();
                    if (count == null) {
                        String msgBody = messageSend.getMsgBody();
                        JsonNode jsonNode = objectMapper.readTree(msgBody);
                        count = jsonNode.get("count").asInt();
                        long amount = jsonNode.get("amount").asLong();
                        messageSend.setCount(count);
                        messageSend.setAmount(amount);
                    }
                    ExportVo exportVo = new ExportVo(messageSend.getMsgId(), messageSend.getCount(), messageSend.getAmount());
                    sendList.add(exportVo);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            return sendList;
        }
    }


}
